package com.sz.biz.common.customer.service.impl;

import com.sz.biz.common.constants.CommCodes;
import com.sz.biz.common.constants.ErrorCodes;
import com.sz.biz.common.constants.ModuleNames;
import com.sz.biz.common.customer.dto.CusBusinessContactsDto;
import com.sz.biz.common.customer.entity.CusBusinessContacts;
import com.sz.biz.common.customer.service.CustomerBusinessContactsService;
import com.sz.common.base.constants.UserActions;
import com.sz.common.base.dao.ParamData;
import com.sz.common.base.dto.CodeNameDto;
import com.sz.common.base.dto.QResultDto;
import com.sz.common.base.dto.QueryParams;
import com.sz.common.base.exception.Exceptions;
import com.sz.common.base.service.AbstractService;
import com.sz.common.base.utils.CollectionUtils;
import com.sz.common.base.utils.StringUtils;
import com.sz.common.core.service.PrincipalLogUtils;
import com.sz.common.core.system.dto.UserDto;
import com.sz.common.core.system.entity.Org;
import com.sz.common.core.system.service.OrgService;
import com.sz.common.core.system.service.UserPositionService;
import com.sz.common.core.system.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * Created by xutao on 17/4/21.
 */
@Service("CustomerBusinessContactsService")
@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
public class CustomerBusinessContactsServiceImpl extends AbstractService implements CustomerBusinessContactsService {

    @Autowired
    UserService userService;
    @Autowired
    OrgService orgService;
    @Autowired
    UserPositionService userPositionService;

    @Override
    public int save(CusBusinessContacts entry) {

        checkDataValid(entry);

        dao.save(getSqlName("insertSelective"), entry);

        //保存操作日志
        Map<String, Object> dataBackup = new HashMap<>();
        dataBackup.put("ADD_CUSTOMER_BUSINESS_CONTACTS", entry);
        PrincipalLogUtils.addOperationLog(ModuleNames.CUS, ModuleNames.CUS_CUSTOMER, UserActions.ADD, "新增客户业务联系人信息", dataBackup);

        return entry.getId();
    }

    @Override
    public int updateById(CusBusinessContacts entry) {

        checkDataValid(entry);

        List<CusBusinessContacts> cusBusinessContactsList = dao.findForList(getSqlName("selectByPrimaryKey"), entry.getId(), CusBusinessContacts.class);

        if (cusBusinessContactsList == null) {

            throw Exceptions.bizException(ErrorCodes.ERROR_MODEL_NOT_FOUND, "business contacts");
        }

        dao.update(getSqlName("updateById"), entry);

        //保存操作日志
        Map<String, Object> dataBackup = new HashMap<>();
        dataBackup.put("ADD_CUSTOMER_BUSINESS_CONTACTS", entry);
        PrincipalLogUtils.addOperationLog(ModuleNames.CUS, ModuleNames.CUS_CUSTOMER, UserActions.UPDATE, "修改客户业务联系人信息", dataBackup);

        return entry.getId();
    }

    @Override
    public void delete(List<Integer> ids) {

        if (ids != null && ids.size() > 0) {

            dao.update(getSqlName("logicDeleteByIds"), ids);
        }

        //保存操作日志
        Map<String, Object> dataBackup = new HashMap<>();
        dataBackup.put("ADD_CUSTOMER_BUSINESS_CONTACTS", ids);
        PrincipalLogUtils.addOperationLog(ModuleNames.CUS, ModuleNames.CUS_CUSTOMER, UserActions.DELETE, "删除客户业务联系人信息", dataBackup);
    }

    @Override
    public QResultDto getContactList(String q, String sortName, boolean isAsc, int pageIndex, int pageSize, int refCustomerId) {

        List<CusBusinessContactsDto> cusBusinessContactsDtos = new ArrayList<>();
        ParamData pd = this.convertQueryParams(new QueryParams(pageSize, pageIndex, q, sortName, isAsc, null).put("refCustomerId", refCustomerId));
        List<CusBusinessContacts> cusBusinessContactsList = dao.findForList(getSqlName("findByParamListPage"), pd, CusBusinessContacts.class);

        boolean isChangedForGorup = false;

        for (int i = 0; i < cusBusinessContactsList.size(); i++) {

            List<Org> orgList = orgService.findByUnDeletedUserId(cusBusinessContactsList.get(i).getRefBussContactId());

            if (orgList != null && orgList.size() > 0) {

                for (int index = 0; index < orgList.size(); index++) {

                    if (cusBusinessContactsList.get(i).getRefBussGroupCode().equalsIgnoreCase(orgList.get(index).getCode())) {
                        isChangedForGorup = false;
                        break;
                    }

                    if (index == orgList.size() - 1) {
                        isChangedForGorup = true;
                    }
                }
            }

            CusBusinessContacts contact = cusBusinessContactsList.get(i);
            CusBusinessContactsDto cusBusinessContactsDto = new CusBusinessContactsDto();
            cusBusinessContactsDto.setId(contact.getId());
            cusBusinessContactsDto.setUserId(contact.getRefBussContactId());
            cusBusinessContactsDto.setGroupCode(contact.getRefBussGroupCode());
            cusBusinessContactsDto.setDescription(contact.getDescription());

            cusBusinessContactsDto.setChangedForGorup(isChangedForGorup);

            UserDto user = userService.getUserById(contact.getRefBussContactId());
            if (user != null) {
                cusBusinessContactsDto.setUserName(user.getFullName());
                cusBusinessContactsDto.setUserCode(user.getCode());
                cusBusinessContactsDto.setPhoneNumber(user.getTelephone());
                cusBusinessContactsDto.setCellPhoneNumber(user.getMobilephone());
                cusBusinessContactsDto.setDepartmentName(user.getOrgName());

                if (!StringUtils.isEmpty(user.getPositionCode())) {
                    String positionName = userPositionService.getNameByCode(user.getPositionCode());
                    cusBusinessContactsDto.setPositionName(positionName);
                } else {
                    cusBusinessContactsDto.setPositionName("_");
                }
            }
            String groupName = findGroupNameByCode(contact.getRefBussGroupCode());
            if (groupName != null) {
                cusBusinessContactsDto.setGroupName(groupName);
            }
            cusBusinessContactsDtos.add(cusBusinessContactsDto);
        }

        QResultDto qResultDto = new QResultDto();
        qResultDto.setData(cusBusinessContactsDtos);
        qResultDto.setPagination(pd.getPagination());

        return qResultDto;
    }

    @Override
    public CusBusinessContactsDto findById(Integer id) {
        CusBusinessContacts contact = (CusBusinessContacts) dao.findForObject(getSqlName("selectByPrimaryKey"), id);
        CusBusinessContactsDto cusBusinessContactsDto = new CusBusinessContactsDto();
        cusBusinessContactsDto.setId(contact.getId());
        cusBusinessContactsDto.setUserId(contact.getRefBussContactId());
        cusBusinessContactsDto.setGroupCode(contact.getRefBussGroupCode());
        cusBusinessContactsDto.setDescription(contact.getDescription());

        UserDto user = userService.getUserById(contact.getRefBussContactId());
        if (user != null) {
            cusBusinessContactsDto.setUserName(user.getFullName());
            cusBusinessContactsDto.setUserCode(user.getCode());
            cusBusinessContactsDto.setPhoneNumber(user.getTelephone());
            cusBusinessContactsDto.setCellPhoneNumber(user.getMobilephone());
            cusBusinessContactsDto.setDepartmentName(user.getOrgName());
        }
        String groupName = findGroupNameByCode(contact.getRefBussGroupCode());
        if (groupName != null) {
            cusBusinessContactsDto.setGroupName(groupName);
        }
        return cusBusinessContactsDto;
    }

    @Override
    public List<CusBusinessContacts> findByCustomerId(Integer refCustomerId) {

        List<CusBusinessContacts> cusBusinessContactsList = dao.findForList(getSqlName("findByCustomerId"), refCustomerId, CusBusinessContacts.class);

        return cusBusinessContactsList;
    }

    @Override
    public List<CusBusinessContacts> findByCustomerIdAndGroupCode(Integer refCustomerId, String groupCode) {
        List<CusBusinessContacts> cusBusinessContacts = findByCustomerId(refCustomerId);
        if (cusBusinessContacts == null) {
            return null;
        } else {
            return cusBusinessContacts.stream().filter(e ->
                    e.getRefBussGroupCode().equalsIgnoreCase(groupCode)
            ).collect(Collectors.toList());
        }
    }

    /**
     * 根据客户的账户id、业务组，来获取一个随机的客服人员
     *
     * @param refCustomerId 客户的账户id
     * @param groupCode     public static final String CUS_BUS_CONTACT_SYS_GROUP_SALES = "SYS-GROUP-SALES";//销售
     *                      public static final String CUS_BUS_CONTACT_SYS_GROUP_FD = "SYS-GROUP-FD";//财务
     *                      public static final String CUS_BUS_CONTACT_SYS_GROUP_CSD = "SYS-GROUP-CSD";//客服
     * @return 一个随机的客服，如果没有客服人员则返回0;
     */
    @Override
    public int findRandomBussIdByCustomerIdAndGroupCode(Integer refCustomerId, String groupCode) {
        int bussContactId = 0;
        List<CusBusinessContacts> cusBusinessContactsList = this.findByCustomerIdAndGroupCode(refCustomerId, groupCode);
        if (!CollectionUtils.isEmpty(cusBusinessContactsList)) {
            int index = (int) (Math.random() * cusBusinessContactsList.size());
            CusBusinessContacts cusBusinessContacts = cusBusinessContactsList.get(index);
            bussContactId = cusBusinessContacts.getRefBussContactId();
        }
        return bussContactId;
    }

    private void checkDataValid(CusBusinessContacts cusBusinessContacts) {

        if (StringUtils.isEmpty(cusBusinessContacts.getRefBussGroupCode())) {

            throw Exceptions.bizException(ErrorCodes.ERROR_ARGUMENT_EMPTY, "BussGroupCode");
        }

        if (cusBusinessContacts.getRefBussContactId() == 0) {

            throw Exceptions.bizException(ErrorCodes.ERROR_ARGUMENT_EMPTY, "BussContactId");
        }

        if (cusBusinessContacts.getRefCustomerId() == 0) {

            throw Exceptions.bizException(ErrorCodes.ERROR_ARGUMENT_EMPTY, "CustomerId");
        }
    }

    @Override
    public Boolean checkContactsExist(CusBusinessContacts entry) {

        CusBusinessContacts cusBusinessContacts = (CusBusinessContacts) dao.findForObject(getSqlName("isExistForContact"), entry);


        return cusBusinessContacts != null;

    }

    @Override
    public List<CodeNameDto> getBusinessContactsGroupList() {

        List<CodeNameDto> codeNameDtoList = new ArrayList<CodeNameDto>();

        CodeNameDto codeNameDto1 = new CodeNameDto();

        codeNameDto1.setName("销售");
        codeNameDto1.setCode("SYS-GROUP-SALES");

        CodeNameDto codeNameDto2 = new CodeNameDto();

        codeNameDto2.setName("财务");
        codeNameDto2.setCode("SYS-GROUP-FD");

        CodeNameDto codeNameDto3 = new CodeNameDto();

        codeNameDto3.setName("客服");
        codeNameDto3.setCode("SYS-GROUP-CSD");

        codeNameDtoList.add(codeNameDto1);
        codeNameDtoList.add(codeNameDto2);
        codeNameDtoList.add(codeNameDto3);

        return codeNameDtoList;
    }

    public String findGroupNameByCode(String groupCode) {

        String res = null;

        if (groupCode.equalsIgnoreCase(CommCodes.CUS_BUS_CONTACT_SYS_GROUP_SALES)) {

            res = "销售";
        }

        if (groupCode.equalsIgnoreCase(CommCodes.CUS_BUS_CONTACT_SYS_GROUP_FD)) {

            res = "财务";
        }

        if (groupCode.equalsIgnoreCase(CommCodes.CUS_BUS_CONTACT_SYS_GROUP_CSD)) {

            res = "客服";
        }

        return res;
    }

    @Override
    protected String getMapperNamespace() {
        return "CusBusinessContactsMapper";
    }
}
